﻿#include "com_rs485.h"

#include "crc.h"

#include <QFloat16>

#pragma execution_character_set("utf-8")


Rs485Com::Rs485Com(QObject* parent)
	: QThread{ parent }
{
	unsigned short crc;

	// 初始化报文
	//读电机实际速度
	unsigned char hex[8]{ 0x04, 0x03, 0x20, 0x2c, 0x00, 0x01 };
	for (int i = 0; i < 4; i++)
	{
		hex[0] = i + 1;
		crc = CRC16(hex, 6);
		hex[6] = static_cast<unsigned char>(crc);
		hex[7] = static_cast<unsigned char>(crc >> 8);
		readSpeed[i] = QByteArray((char*)hex, 8);
	}


	// 串口类必须在 moveToThread 之前初始化，否则程序会 crash（崩溃）
	port = new QSerialPort();


	//// 创建用于485 通信的线程
	//subThread = new QThread;

	//this->moveToThread(subThread);
	//port->moveToThread(subThread);

	//// 启动线程
	//subThread->start();
}

void Rs485Com::initPort(const QString& portName)
{
	// 如果串口已打开
	if (this->port->isOpen())
	{
		this->port->clear();// 清除缓冲区数据，终止读写操作
		this->port->close();// 关闭串口
	}
	// 设置要打开的串口名
	this->port->setPortName(portName);

	if (!this->port->open(QIODevice::ReadWrite))
	{
		emit failed();// 打开串口失败信号
	}
	else
	{
		this->port->setBaudRate(115200, QSerialPort::AllDirections);//设置波特率和读写方向
		this->port->setDataBits(QSerialPort::Data8);              //数据位为8位
		this->port->setFlowControl(QSerialPort::NoFlowControl);   //无流控制
		this->port->setParity(QSerialPort::NoParity);             //无校验位
		this->port->setStopBits(QSerialPort::OneStop);            //一位停止位
		//this->runComSync();
		emit succeed();// 打开串口成功信号
	}
}

void Rs485Com::send_order(unsigned char* hex, int len)
{
	unsigned short crc;
	crc = CRC16(hex, len - 2);
	hex[len - 2] = static_cast<unsigned char>(crc);
	hex[len - 1] = static_cast<unsigned char>(crc >> 8);

	port->write(QByteArray((char*)hex, len));

	QByteArray bytes;

	port->flush();
	port->waitForReadyRead(200);
	bytes.resize(9);
	bytes = port->readAll();
	if (bytes.length() == 0)
		return;

	qDebug() << "接收: " << bytes.toHex();
}

void Rs485Com::send_order(QByteArray byteArray)
{
	port->write(byteArray);


	QByteArray bytes;

	port->flush();
	port->waitForReadyRead(200);
	bytes.resize(9);
	bytes = port->readAll();
	if (bytes.length() == 0)
		return;

	qDebug() << "接收: " << bytes.toHex();

}
void Rs485Com::run()
{
	int c = 0;
	QByteArray bytes;
	unsigned char cdata[2];
	short temp;
	double displacement;
	while (true)
	{
		if (c > 3) { c = 0; }
		// 发出指令
		port->write(readSpeed[c]);
		//qDebug() << "发送: " << readCommand[3].toHex();
		port->flush();
		port->waitForReadyRead(200);
		bytes.resize(9);
		bytes = port->readAll();
		if (bytes.length() > 0)
		{
			qDebug() << "接收: " << bytes.toHex('-');

			int n = bytes[2];

			cdata[0] = bytes[4];
			cdata[1] = bytes[3];

			temp = *(qint16*)(&cdata);// | (cdata[0] << 16) | (cdata[1] << 24);

			displacement = temp / 10.0;

			//emit result(c, displacement);
			emit result(c, displacement);
			//	emit result(2, displacement);
		}
		c++;

		//QThread::sleep(100);
	}
}

SubThread::SubThread()
{
	unsigned short crc;

	// 初始化报文
	//读电机实际速度
	unsigned char hex[8]{ 0x04, 0x03, 0x20, 0x2c, 0x00, 0x01 };
	for (int i = 0; i < 4; i++)
	{
		hex[0] = i + 1;
		crc = CRC16(hex, 6);
		hex[6] = static_cast<unsigned char>(crc);
		hex[7] = static_cast<unsigned char>(crc >> 8);
		readSpeed[i] = QByteArray((char*)hex, 8);
	}
}
void SubThread::run(void)
{
	int c = 0;
	QByteArray bytes;
	unsigned char cdata[2];
	short temp;
	double displacement;
	while (true)
	{
		//if (c > 3) { c = 0; }
		// 发出指令
		com485->port->write(readSpeed[c]);
		//qDebug() << "发送: " << readCommand[3].toHex();
		com485->port->flush();
		com485->port->waitForReadyRead(200);
		bytes.resize(9);
		bytes = com485->port->readAll();
		if (bytes.length() == 0)
			continue;


		qDebug() << "接收: " << bytes.toHex('-');

		int n = bytes[2];

		cdata[0] = bytes[4];
		cdata[1] = bytes[3];

		temp = *(qint16*)(&cdata);// | (cdata[0] << 16) | (cdata[1] << 24);

	//	float d = 1;
	//	qint16 asd = 100;
	//	displacement = *(qfloat16*)&cdata;// / 1000.0;

		emit result(1, temp);
		emit result(2, displacement);

		//c++;

		//	QThread::sleep(10);
	}
}